# -*- coding: utf-8 -*-
"""
-------------------------------------------------
File Name： api_logging_route
Description :
Author : 'Mark.Wei'
date： 2022/5/26
Change Activity:
2022/5/26:
-------------------------------------------------
"""

from fastapi import Request, Response
from fastapi.routing import APIRoute
from typing import Callable
from urllib.parse import parse_qs

from ml import logger


class ApiLoggingRoute(APIRoute):
    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            # basic reqeust info
            ip, method, url = request.client.host, request.method, request.url.path
            # request form
            try:
                body_form = await request.form()
            except:
                body_form = None

            # request body
            body = None
            try:
                body_bytes = await request.body()
                if body_bytes:
                    try:
                        body = await request.json()
                    except:
                        if body_bytes:
                            try:
                                body = body_bytes.decode('utf-8')
                            except:
                                body = body_bytes.decode('gb2312')
            except:
                pass

            response = await original_route_handler(request)

            res = None
            if isinstance(response, Response):
                res = str(response.body, encoding='utf-8')

            log_msg = {
                'url': url,
                'method': method,
                'ip': ip,
                'params': {
                    'query_params': parse_qs(str(request.query_params)),
                    'from': body_form,
                    'body': body
                },
                'response': res
            }
            logger.info(log_msg)

            return response

        return custom_route_handler
